#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <time.h>
#include <vector>
#include<easyx.h>

// 游戏窗口尺寸
const int WIDTH = 480;
const int HEIGHT = 640;

// 游戏对象基类
class GameObject {
public:
    int x, y;           // 坐标
    int width, height;  // 尺寸
    bool active;        // 激活状态
public:
    GameObject(int x, int y, int w, int h) : x(x), y(y), width(w), height(h), active(true) {}
    virtual void Draw() = 0;  // 纯虚函数
    bool CheckCollision(const GameObject& other) const {
        return x < other.x + other.width &&
            x + width > other.x &&
            y < other.y + other.height &&
            y + height > other.y;
    }
    bool IsActive() const { return active; }
};

// 玩家飞机类
class Player : public GameObject {
    int speed = 5;
    int bulletCooldown = 0;
public:
    Player() : GameObject(WIDTH / 2, HEIGHT - 100, 50, 50) {}

    void Update() {
        // 处理移动输入
        if (GetAsyncKeyState(VK_LEFT) & 0x8000)  x = max(0, x - speed);
        if (GetAsyncKeyState(VK_RIGHT) & 0x8000) x = min(WIDTH - width, x + speed);
        if (GetAsyncKeyState(VK_UP) & 0x8000)    y = max(0, y - speed);
        if (GetAsyncKeyState(VK_DOWN) & 0x8000)  y = min(HEIGHT - height, y + speed);

        // 处理射击冷却
        if (bulletCooldown > 0) bulletCooldown--;
    }

    void Draw() override {
        IMAGE a;
        loadimage(&a, "assets/player.png", 50, 50);
        putimage(x, y, &a);
    }

    bool TryShoot() {
        if (bulletCooldown == 0) {
            bulletCooldown = 10;
            return true;
        }
        return false;
    }
};

// 子弹类
class Bullet : public GameObject {
    int speed = 8;
public:
    Bullet(int x, int y) : GameObject(x, y, 10, 20) {}
     
    void Update() {
        y -= speed;
        if (y < -height) active = false;
    }

    void Draw() override {
        IMAGE b;
        loadimage(&b, "assets/bullet.png", 10, 10);
        putimage(x, y, &b);
    }
};

// 敌机类
class Enemy : public GameObject {
    int speed = 2;
public:
    Enemy() : GameObject(rand() % (WIDTH - 50), -60 - rand() % 300, 50, 50) {
        speed += rand() % 3;
    }

    void Update() {
        y += speed;
        if (y > HEIGHT) Reset();
    }

    void Draw() override {
        IMAGE c;
        loadimage(&c, "assets/enemy.png", 40, 40);
        putimage(x, y, &c);
    }

    void Reset() {
        x = rand() % (WIDTH - width);
        y = -height - rand() % 300;
        speed = 2 + rand() % 3;
        active = true;
    }
};

class Game {
    Player player;
    std::vector<Bullet> bullets;
    std::vector<Enemy> enemies;
    int score = 0;
    bool gameOver = false;
    const int MAX_ENEMIES = 5;

public:
    Game() {
        srand((unsigned)time(NULL));
        enemies.reserve(MAX_ENEMIES);
        for (int i = 0; i < MAX_ENEMIES; ++i) {
            enemies.emplace_back();
        }
    }

    void Reset() {
        player = Player();  // 重置玩家位置
        bullets.clear();    // 清空子弹列表
        enemies.clear();    // 清空敌机列表
        for (int i = 0; i < MAX_ENEMIES; ++i) {
            enemies.emplace_back();  // 重新生成敌机
        }
        score = 0;         // 重置分数
        gameOver = false;  // 重置游戏结束标志
    }

    void HandleInput() {
        // 发射子弹
        if ((GetAsyncKeyState(VK_SPACE) & 0x8000) && player.TryShoot()) {
            bullets.emplace_back(player.x + 1 - 5, player.y);
        }
    }

    void Update() {
        if (gameOver) return;

        player.Update();

        // 更新子弹
        for (auto& bullet : bullets) {
            bullet.Update();
        }

        // 更新敌机
        for (auto& enemy : enemies) {
            enemy.Update();
        }

        CheckCollisions();
    }

    void Draw() {
        cleardevice();

        // 绘制背景
        setbkcolor(BLACK);
        setfillcolor(BLACK);
        fillrectangle(0, 0, WIDTH, HEIGHT);

        // 绘制游戏对象
        player.Draw();
        for (auto& bullet : bullets) {
            if (bullet.IsActive()) bullet.Draw();
        }
        for (auto& enemy : enemies) {
            if (enemy.IsActive()) enemy.Draw();
        }

        // 绘制UI
        char scoreText[20];
        sprintf_s(scoreText, "Score: %d", score);
        settextcolor(WHITE);
        outtextxy(10, 10, scoreText);

        if (gameOver) {
            settextcolor(RED);
            settextstyle(48, 0, _T("Arial"));
            outtextxy(WIDTH / 2 - 100, HEIGHT / 2 - 30, _T("Game Over"));
            settextstyle(24, 0, _T("Arial"));
            outtextxy(WIDTH / 2 - 120, HEIGHT / 2 + 20, _T("在输入框中按下R或r以重开"));
        }

        FlushBatchDraw();
    }

private:
    void CheckCollisions() {
        // 子弹与敌机碰撞检测
        for (auto& bullet : bullets) {
            if (!bullet.IsActive()) continue;

            for (auto& enemy : enemies) {
                if (enemy.IsActive() && bullet.CheckCollision(enemy)) {
                    bullet.active = false;
                    enemy.Reset();
                    score += 10;
                }
            }
        }

        // 玩家与敌机碰撞检测
        for (auto& enemy : enemies) {
            if (enemy.IsActive() && player.CheckCollision(enemy)) {
                gameOver = true;
                return;
            }
        }
    }
};

int main() {
    initgraph(WIDTH, HEIGHT);
    BeginBatchDraw();

    Game game;

    while (true) {
        // 处理退出
        if (_kbhit()) {
            char key = _getch();
            if (key == 27) break; // ESC退出
            if (key == 'r' || key == 'R') { // 按下R键重新开始
                game.Reset();  // 调用Reset方法重新开始游戏
                continue;      // 重新开始游戏逻辑
            }
        }

        game.HandleInput();
        game.Update();
        game.Draw();
        Sleep(10);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}